package pwd.allen.demo.controller;

import pwd.allen.demo.util.AesUtil;
import pwd.allen.password.CheckMsg;
import pwd.allen.password.ICheckRule;
import pwd.allen.password.annotation.CheckParam;
import pwd.allen.password.annotation.WeakPwdCheck;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;

/**
 * @author 门那粒沙
 * @create 2022-01-08 10:34
 **/
@RequestMapping("test")
@RestController
public class TestController {

    private static final Logger logger = LoggerFactory.getLogger(TestController.class);

    /**
     * 弱密码校验工具
     */
    @Autowired
    private ICheckRule checkRule;

    /**
     * 默认的注解方式，验证失败直接返回错误json
     *
     * @param username
     * @param password
     * @return
     */
    @WeakPwdCheck
    @GetMapping("login")
    public Object login(@RequestParam("username") String username, @RequestParam("password") @CheckParam() String password) {
        logger.info("用户名：{}，密码：{}", username, password);

        HashMap<String, Object> map = new HashMap<>();
        map.put("type", "success");
        map.put("msg", "登录成功");
        return map;
    }


    /**
     * 直接使用弱密码校验工具
     *
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("manual")
    public Object manual(@RequestParam("username") String username, @RequestParam("password") String password) {
        logger.info("用户名：{}，密码：{}", username, password);

        //<editor-fold desc="如果密码有特殊处理，或者返回格式比较特殊，可手动使用checkRule进行校验判断逻辑">
        CheckMsg check = checkRule.check(password);
        if (check.getType() == CheckMsg.Type.NOPASS) {
            logger.info("密码为{}，登录失败！", password);
            HashMap<String, Object> map = new HashMap<>();
            map.put("type", "error");
            map.put("msg", "登录失败");
            map.put("data", check);
            return map;
        }
        //</editor-fold>

        HashMap<String, Object> map = new HashMap<>();
        map.put("type", "success");
        map.put("msg", "登录成功");
        return map;
    }

    /**
     * 验证失败时转发给其他方法
     *
     * @param request
     * @param password
     * @return
     */
    @WeakPwdCheck
    @RequestMapping("forward")
    public Object forward(HttpServletRequest request, @RequestParam("password") @CheckParam(urlForward = "/test/error") String password) {
        logger.info("密码为{}，登录成功！", password);
        return "success";
    }

    /**
     * 验证失败时重定向给其他方法
     *
     * @param request
     * @param password
     * @return
     */
    @WeakPwdCheck
    @RequestMapping("redirect")
    public Object redirect(HttpServletRequest request, @RequestParam("password") @CheckParam(urlRedirect = "http://www.baidu.com") String password) {
        logger.info("密码为{}，登录成功！", password);
        return "success";
    }

    /**
     * 验证密码解析功能
     * <p>
     * 说明：通过method4Parse指定同个类里的解析方法名，验证时会调用解析密码
     *
     * @param request
     * @param password
     * @return
     */
    @WeakPwdCheck
    @RequestMapping("parse")
    public Object parse(HttpServletRequest request, @RequestParam("password") @CheckParam(method4Parse = "parsePwd") String password) {
        try {
            password = parsePwd(password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.info("密码为{}，登录成功！", password);
        return "success";
    }
    public String parsePwd(String pwd) throws Exception {
        return AesUtil.decryptAES(pwd);
    }



    /**
     * 自定义验证失败的返回结果
     * <p>
     * 默认配置：默认情况验证失败会以json形式直接返回验证失败结果
     * 使用场景：验证失败想自定义返回结果，或者跳转到指定的错误页面
     *
     * @param req
     * @return
     */
    @RequestMapping("error")
    public Object error(HttpServletRequest req) {
        CheckMsg checkMsg = (CheckMsg) req.getAttribute("checkMsg");
        HashMap<String, Object> map = new HashMap<>();
        map.put("msg", checkMsg.getMsg());
        map.put("type", checkMsg.getType());
        map.put("test", "弱密码校验测试");
        return map;
    }
}
